package net.maku.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse;

import cn.hutool.core.convert.Convert;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.maku.bean.dto.ImgSvrRetDto;
import net.maku.bean.model.MyException;
import net.maku.bean.query.WebPayRecordQuery;
import net.maku.bean.vo.PayOrderVo;
import net.maku.bean.vo.TestResultVO;
import net.maku.bean.vo.WebPayConfigVO;
import net.maku.config.WxConfigProperties;
import net.maku.constant.CaffeineKeyConstant;
import net.maku.entity.WebIncomeRecordEntity;
import net.maku.entity.WebPayConfigEntity;
import net.maku.entity.WebPayRecordEntity;
import net.maku.entity.WebTradeRecordEntity;
import net.maku.entity.WebUserEntity;
import net.maku.utils.CaffeineUtils;
import net.maku.utils.JsonUtils;
import net.maku.utils.MyBeanUtils;
import net.maku.utils.Result;
import net.maku.utils.TokenUtils;

@Slf4j
@Service
@AllArgsConstructor
public class BizTradeServiceImpl {

	@PostConstruct
	public List<WebPayConfigVO> getPayConfig() {
		 List<WebPayConfigVO> tlist = (List<WebPayConfigVO>) CaffeineUtils.getCache( CaffeineKeyConstant.PAY_TYPE_KEY );
		 if(tlist==null || tlist.size()<=0) {
			 List<WebPayConfigEntity> list = webPayConfigServiceImpl.list();
			 System.out.println("getPayConfig: "+ list.toString() );
			 //tlist = WebPayConfigConvert.INSTANCE.convertList(list);
			 tlist = MyBeanUtils.copyObjToList(list, WebPayConfigVO.class);
			 CaffeineUtils.putCache( CaffeineKeyConstant.PAY_TYPE_KEY, list );
			 Map<String, WebPayConfigVO> map = new HashMap<String, WebPayConfigVO>();
			 for(int i=0; i<tlist.size(); i++ ) {
				 map.put(tlist.get(i).getBuytype(), tlist.get(i));
				 log.info( tlist.toString() );
			 }
			 CaffeineUtils.putCache( CaffeineKeyConstant.PAY_TYPE_KEY_MAP, map );
		 }

		 List<WebPayConfigVO> volist = MyBeanUtils.copyObjToList(tlist, WebPayConfigVO.class);
		 for(int i=0; i<volist.size(); i++ ) {
			 volist.get(i).setAmount( (Convert.toFloat(volist.get(i).getAmount())/100.0) +"");
		 }
		 log.info("加载支付配置：" + volist.toString());
		 return volist;
	 }
	
	
	/**
	class PrepayWithRequestPaymentRequest {
    appId: wx6ed1af0b9fdd0456
    timestamp: 1726374314
    nonceStr: B61olCO2nrcOUqz9hKM3qICzAANyHP3a
    packageVal: prepay_id=wx151225158835407a8e98c8cfdaf29a0000
    signType: RSA
    paySign: EP9daVWk9qpEAzRl/BejoM3GjqzRuvVTd7ksyRNBe7qfTVC6onglytHD58e7J9jG+JlqPrIemsf3Jvyqq1NwrzXRaxUvZZ2pludrqd+AXyl7MRxrPIcnqWMRtwhgN3ZDgcsdxaXGL6YQXL01JCYE2Pbf4+KWc0/dRFlptaISKOrm0lfszEpgcd7rJwZo3Ijthq7C4OXLbliWD9ZYc2x8UIEBP7I8+0hBveuaGjPtNJQh9sbJgDPzugc4LeaqJ4kgL6Ljq45/uB44igw9en1FBYSyw7i9pXgbKjombWEnbwdGy801SjXrgM+Z9oho70NIJctcar5zsQWzvBVFwPKckw==
	}
    */
	
	//@Value("${spring.profiles.active}")
    //private String activeProfile;
	
	@Autowired
	private Environment environment;
	
	//调用微信支付
	public PayOrderVo callWxPay(WebPayRecordQuery query) {
		log.info( query.toString() );
		String  buytype = query.getTradeType();
      	Map<String, WebPayConfigVO> map = (Map<String, WebPayConfigVO>) CaffeineUtils.getCache( CaffeineKeyConstant.PAY_TYPE_KEY_MAP );
    	WebPayConfigVO vo = map.get(query.getTradeType());
    	Integer payAmount = Convert.toInt(vo.getAmount());
    	WebUserEntity webUserEntity = TokenUtils.getUserBean();
    	WebPayRecordEntity pentity = new WebPayRecordEntity();
    	pentity.setUserid(webUserEntity.getId().toString());
    	if(query.getDeviceType()==1) {
    		pentity.setPayerOpenid(webUserEntity.getAppopenid());
    	}else {
    		pentity.setPayerOpenid(webUserEntity.getOpenid());
    	}
    	pentity.setAmount(payAmount);
    	pentity.setBuytype(buytype);
    	pentity.setCountnum(vo.getCountnum());
    	pentity.setStatus(0);
    	webPayRecordServiceImpl.save(pentity);
    	String transactionId = "";
    	String activeProfile = environment.getProperty("spring.profiles.active");
    	log.info( "spring.profiles.active: " + activeProfile );
    	if( activeProfile!=null && activeProfile.equalsIgnoreCase("prod")){
    		transactionId = String.format("trade_no_%09d", pentity.getId());
    	}else {
    		transactionId = String.format("trade_no_%08d", pentity.getId());
    	}
    	log.info( "transactionId: " + transactionId );
    	pentity.setOutTradeNo(transactionId);
    	webPayRecordServiceImpl.updateById(pentity);

        try {
        	//收款人信息
            PrepayRequest request = new PrepayRequest();
            request.setAppid( wxConfigProperties.getAppId() );
            request.setMchid( wxConfigProperties.getMchId() );
            request.setDescription("读心网AI点数");
            //request.setNotifyUrl("http://duxinai.com/api/notify");
            request.setNotifyUrl( wxConfigProperties.getNotifyUrl() );
            request.setOutTradeNo(transactionId);

            //支付金额
            Amount amount = new Amount();
            amount.setTotal( payAmount );
            request.setAmount(amount);
            //支付人
            Payer payer = new Payer();
            payer.setOpenid( pentity.getPayerOpenid() );
            request.setPayer(payer);
            log.info("请求预支付下单，请求参数：{}\n", JsonUtils.toJson(request));
            // 调用预下单接口
            PrepayWithRequestPaymentResponse response 
            		= jsapiService.prepayWithRequestPayment(request);
            log.info("订单发起预支付成功，返回信息：{}\n", JsonUtils.toJson(response) );
            PayOrderVo payVo = new PayOrderVo();
            payVo.setAppid(wxConfigProperties.getAppId());
            payVo.setNonceStr(response.getNonceStr());
            payVo.setPartnerid( wxConfigProperties.getMchId() );
            payVo.setPpackage(response.getPackageVal());
            payVo.setTimeStamp(response.getTimeStamp());
            payVo.setSignType(response.getSignType() );
            payVo.setPaySign( response.getPaySign() );
            return payVo;
        } catch ( Exception e) { // 发送HTTP请求失败
            log.error("微信下单错误信息：{}", e.getMessage() );
        	e.printStackTrace();
        }
        throw new MyException("调用微信支付失败");
	}
	
	//用户充值
	public void wxCallBackTrade( String OutTradeNo, String transactionId) {
		QueryWrapper<WebPayRecordEntity> wrapper = new QueryWrapper<WebPayRecordEntity>();
        wrapper.eq("out_trade_no", OutTradeNo );
        WebPayRecordEntity payEntity = webPayRecordServiceImpl.getOne(wrapper);
        payEntity.setTransactionId(transactionId);
        payEntity.setStatus(1);
        webPayRecordServiceImpl.updateById(payEntity);
        
        
        WebTradeRecordEntity tradEntity = new WebTradeRecordEntity();
        tradEntity.setOpenid(payEntity.getPayerOpenid());
        tradEntity.setUserid(payEntity.getUserid());
        tradEntity.setStatus(1);
        tradEntity.setType("1");
    	tradEntity.setCountnum(payEntity.getCountnum());
    	tradEntity.setTransactionId(payEntity.getTransactionId());
    	webTradeRecordServiceImpl.save(tradEntity);
    	
    	
    	WebUserEntity entity = webUserServiceImpl.getById(payEntity.getUserid());
    	entity.setCountnum(entity.getCountnum()+payEntity.getCountnum());
    	if(StringUtils.isNotBlank(entity.getBrefcode()) && entity.getIsfirst()==0 ) {
    		allocationTrade( entity, payEntity );
    		entity.setIsfirst(1);
    	}
    	webUserServiceImpl.updateById(entity);
    }
	
	//给用户分佣金
	public void allocationTrade( WebUserEntity payUser, WebPayRecordEntity peyEntity ) {
		QueryWrapper<WebUserEntity> wrapper = new QueryWrapper<WebUserEntity>();
        wrapper.eq("refcode", payUser.getBrefcode() );
        List<WebUserEntity> list = webUserServiceImpl.list(wrapper);
        if(list.size()<=0) {
        	return ;
        }
        
        //保存用户收益
        WebUserEntity userEntity = list.get(0);
        Integer amount = peyEntity.getAmount() * Convert.toInt(wxConfigProperties.getAllocation())/100;
        if(amount<=0) {
        	amount = peyEntity.getAmount();
        }
        System.out.println("amount=============: " + peyEntity.getAmount());
        System.out.println("amount=============: " + amount);
        userEntity.setIncome( Convert.toInt(userEntity.getIncome())+amount);
        webUserServiceImpl.update(userEntity);

        //保存用户收益记录
        WebIncomeRecordEntity incomeEntity = new WebIncomeRecordEntity();
        incomeEntity.setUserid(list.get(0).getId().toString());
        incomeEntity.setOpenid(list.get(0).getOpenid() );
        incomeEntity.setPayerPayid(payUser.getId().toString());
        incomeEntity.setPayerOpenid(payUser.getOpenid() );
        incomeEntity.setOrderid(peyEntity.getId().toString());
        incomeEntity.setAllocation(wxConfigProperties.getAllocation());
        incomeEntity.setPayeramount(amount.toString());
        incomeEntity.setAmount(amount.toString());
        webIncomeRecordServiceImpl.save(incomeEntity);
	}

	public TestResultVO getTestResult( MultipartFile upfile ) {
		TestResultVO vo = new TestResultVO();
		WebUserEntity webUserEntity = TokenUtils.getUserBean();
		WebUserEntity entity = webUserServiceImpl.getById(webUserEntity.getId());
		if(entity.getCountnum()<=0) {
			vo.setCode(-1);
			vo.setUsername( entity.getUsername() );
			vo.setContent( "用户点数不足，请充值后再测试。" );
			return vo;
		}
		/*
		if( checkFace(upfile) !=1 ) {
			vo.setCode(-1);
			vo.setUsername( entity.getUsername() );
			vo.setContent( "图片上人脸个数异常, 不能测试。" );
			return vo;
		}*/

		ImgSvrRetDto dto = null;
		try {
			dto = postData( upfile.getBytes()  );
		} catch (Throwable e) {
			e.printStackTrace();
			log.error("调用测评服务：", e);
			vo.setCode(-1);
			vo.setUsername( entity.getUsername() );
			vo.setContent( "调用测试服务失败，本次测试平台不会扣除用户点数。" );
			return vo;
		}
		
		entity.setCountnum(entity.getCountnum()-1);
		webUserServiceImpl.update(entity);
		WebTradeRecordEntity tentity = new WebTradeRecordEntity();
		tentity.setOpenid(entity.getOpenid());
		tentity.setUserid(entity.getId().toString());
		tentity.setCountnum(1);
		tentity.setStatus(1);
		tentity.setType("0");
		webTradeRecordServiceImpl.save(tentity);
 
		vo.setUsername( entity.getUsername() );
		log.info("==============getTestResult===================");
		log.info(dto.getAnalyes_ret());
		String ret = dto.getAnalyes_ret().replaceAll("\n\n", "<br />");
		ret  = ret.replaceAll("\n", "<br />");
		log.info(ret);
		vo.setContent( ret );
		return vo;
	}
	
	public ImgSvrRetDto postData( byte bytes[]  ) {
    	// 定义请求参数和url链接
    	String url = wxConfigProperties.getOpenaiUrl();
    	System.out.println("通过url： "+url);
    	log.info("通过url： "+url);
    	MultiValueMap<String, Object> params = new LinkedMultiValueMap<String, Object>();
    	String base64_image  = Base64.encodeBase64String(bytes);
    	params.add("image_base64", base64_image );
    	//System.out.println(base64_image );
    	// 创建 HttpHeaders 对象，并设置 Content-Type 为 application/x-www-form-urlencoded
    	HttpHeaders headers = new HttpHeaders();
    	headers.setContentType(MediaType.APPLICATION_JSON);
    	// 使用 MultiValueMap 类型创建请求体，并将参数放入其中
    	HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
    	// 调用 RestTemplate 方法进行请求
    	ResponseEntity<String> response = restTemplate.postForEntity(url, requestEntity, String.class);
    	// 获取请求结果并处理
    	if ( response.getStatusCode() == HttpStatus.OK ) {
    	    String result = response.getBody();
    	    System.out.println( result );
    	    ImgSvrRetDto dto = JsonUtils.fromJson(result, ImgSvrRetDto.class);
    	    log.info("图像处理结果: {}", result);
    	    if( dto.getCode()!=200 ) {
    	    	throw new MyException("图像处理处理失败");
    	    }
    	    return dto;
    	}
    	throw new MyException("图像处理异常");
    }

	@Autowired
	RestTemplate restTemplate;
	
	@Autowired
	JsapiServiceExtension jsapiService;

	@Autowired
	WxConfigProperties  wxConfigProperties;
	
	@Autowired
	WebIncomeRecordServiceImpl webIncomeRecordServiceImpl;
	
	@Autowired
	WebUserServiceImpl webUserServiceImpl;
	
	@Autowired
	WebPayConfigServiceImpl webPayConfigServiceImpl;
	 
	@Autowired
	WebPayRecordServiceImpl   webPayRecordServiceImpl;
	 
	@Autowired
	WebTradeRecordServiceImpl webTradeRecordServiceImpl;
}




